package com.chenju.invokechainservice.adapter;

import com.chenju.invokechainservice.common.enums.EasyCode;
import com.chenju.invokechainservice.utils.FunnyStringUtils;
import org.objectweb.asm.*;

import java.util.ArrayList;
import java.util.List;

public class SpringBeanClassAdapter extends ClassVisitor {
    private boolean isSpringBean = false;
    private boolean isAspect = false;
    public List<MethodNodeAdapter> methods;
    public String name;

    public SpringBeanClassAdapter() {
        super(Opcodes.ASM9);
        this.methods = new ArrayList<>();
    }

    @Override
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        this.name = name;
    }

    @Override
    public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
        if (visible){
            String className = FunnyStringUtils.findDotString(Type.getType(descriptor).getClassName());
            isSpringBean = isSpringBean || isSpringBeanAnnotation(className);
            isAspect = isAspect || isAspectAnnotation(className);
        }
        return super.visitAnnotation(descriptor, visible);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodNodeAdapter method = new MethodNodeAdapter(access, name, descriptor, signature, exceptions);
        if (!"<clinit>".equals(name) && !"<init>".equals(name) && this.name.startsWith("com/chenju")){
            if (!this.methods.contains(method)){
                this.methods.add(method);
            }
        }
        return method;
    }

    public boolean isSpringBean() {
        return isSpringBean;
    }

    public boolean isAspect() {
        return isAspect;
    }

    public boolean isSpringBeanAnnotation(String annotationFullName){
        if (EasyCode.springBeanAnnotationList.contains(annotationFullName)){
            return true;
        }
        return false;
    }

    public boolean isAspectAnnotation(String annotationFullName){
        if ("org.aspectj.lang.annotation.Aspect".equals(annotationFullName)){
            return true;
        }
        return false;
    }
}
